﻿Imports System.Xml
''' <summary>
''' 语句控制类
''' </summary>
''' <remarks></remarks>
Public Class clsStatementControl
    ''' <summary>
    ''' 根据语句获取动作节点
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function GetSingleOpr(ByVal CurrentText As String) As XmlElement
        Dim SingleXml As XmlElement = Nothing
        Dim SingleComment As String = String.Empty
        Dim SingleLineWithOutComment As String = CurrentText
        If InStr(CurrentText, "*/") > 0 Then
            SingleLineWithOutComment = ClearComment(CurrentText)
        End If
        If InStr(CurrentText, "*/") > 0 Then
            SingleComment = GetComment(CurrentText)
            SingleComment = Mid(SingleComment, 2, SingleComment.Length - 2)
        End If
        'SingleLineWithOutComment 为空的情况在上层过滤掉了
        SingleLineWithOutComment = SingleLineWithOutComment.Trim
        '删除末尾一个分号
        If SingleLineWithOutComment.EndsWith(";") Then
            SingleLineWithOutComment = Mid(SingleLineWithOutComment, 1, SingleLineWithOutComment.Length - 1)
        End If
        'INCLUDE
        SingleXml = clsStatementInclude.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'MOVE
        SingleXml = clsStatementMove.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'READ
        SingleXml = clsStatementRead.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'Write
        SingleXml = clsStatementWrite.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'CLOSE
        SingleXml = clsStatementClose.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'CALL
        SingleXml = clsStatementCall.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'GET
        SingleXml = clsStatementGet.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            If TestMode Then SingleXml.SetAttribute("Statement", SingleLineWithOutComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'OPEN
        SingleXml = clsStatementOpen.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'PUT
        SingleXml = clsStatementPut.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'ENDFILE
        SingleXml = clsStatementOnCondition.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'EXEC
        SingleXml = clsStatementEXEC.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'FETCH
        SingleXml = clsStatementFETCH.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'GOTO
        SingleXml = clsStatementGoto.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'LABEL
        SingleXml = clsStatementLabel.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'Leave
        SingleXml = clsStatementLeave.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        'MARCO
        SingleXml = clsStatementMacro.IsStatement(SingleLineWithOutComment)
        If Not SingleXml Is Nothing Then
            SingleXml.SetAttribute("COMMENT", SingleComment)
            AddCommentList(SingleXml)
            Return SingleXml
        End If
        Dim UndifinedXml As Xml.XmlElement = mXmlDocument.CreateElement("Undifined")
        UndifinedXml.SetAttribute("Statement", SingleLineWithOutComment)
        UndifinedXml.SetAttribute("COMMENT", SingleComment)
        AddCommentList(UndifinedXml)
        Return UndifinedXml
    End Function
    ''' <summary>
    ''' 将积累下来的整行注释加入某个元素中
    ''' </summary>
    ''' <param name="SingleXml"></param>
    ''' <remarks></remarks>
    Shared Sub AddCommentList(ByVal SingleXml As XmlElement)
        If GlobalCommentList.Count > 0 Then
            For Each StrComment As String In GlobalCommentList
                Dim commentXml As XmlElement = mXmlDocument.CreateElement("COMMENTLIST")
                commentXml.SetAttribute("TEXT", StrComment)
                SingleXml.AppendChild(commentXml)
            Next
            GlobalCommentList.Clear()
        End If
    End Sub
End Class
''' <summary>
''' ACCEPT相关类
''' </summary>
''' <remarks></remarks>
Public Class clsStatementAccept
    ''' <summary>
    '''生成ACCEPT语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateACCEPT(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        strLine = GetSpace() & "ACCEPT  %target  FROM %function" & IIf(Deepth = 1, ".", String.Empty)
        strLine = strLine.Replace("%target", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("TARGET")))
        strLine = strLine.Replace("%function", mStatement.GetAttribute("FUNCTION"))
        strRtn.Add(strLine)
        Return strRtn
    End Function
    ''' <summary>
    ''' ACCEPT的调整
    ''' </summary>
    ''' <param name="AcceptNode"></param>
    ''' <param name="PreProcess"></param>
    ''' <param name="AfterProcess"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function JustifyAccept(ByVal AcceptNode As XmlElement, ByVal PreProcess As clsStatementBlock, ByVal AfterProcess As clsStatementBlock) As XmlElement
        Select Case AcceptNode.GetAttribute("FUNCTION")
            Case "TIME", "DATETIME"
                'COBOL的毫秒是2位的，PL1的毫秒是3位的，需要进行调整
                Dim StringNode As XmlElement = mXmlDocument.CreateElement("STRING")
                Dim SubStringXml As Xml.XmlElement = mXmlDocument.CreateElement("SUBSTRING")
                SubStringXml.SetAttribute("TEXT", "SUBSTR(" & AcceptNode.GetAttribute("TARGET") & _
                                          ",1," & IIf(AcceptNode.GetAttribute("FUNCTION") = "TIME", "8)", "16)"))
                StringNode.AppendChild(SubStringXml)
                Dim SubStringXml2 As Xml.XmlElement = mXmlDocument.CreateElement("SUBSTRING")
                SubStringXml2.SetAttribute("TEXT", "0")
                StringNode.AppendChild(SubStringXml2)
                StringNode.SetAttribute("TARGET", AcceptNode.GetAttribute("TARGET"))
                AfterProcess.AddOperation(StringNode)
        End Select
        Return AcceptNode
    End Function
    ''' <summary>
    ''' 是否为ACCEPT命令
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        Dim StrSource As String = String.Empty
        Dim StrTarget As String = String.Empty
        For i As Byte = 2 To strwords.Count - 1
            StrSource &= strwords(i) & Space(1)
        Next
        StrSource = StrSource.Trim
        StrTarget = strwords(0).Trim
        If StrSource = "DATE" Or StrSource = "DATE()" Or _
           StrSource = "TIME" Or StrSource = "TIME()" Or _
           StrSource = "DATETIME" Or StrSource = "DATETIME()" Then
            Dim AcceptXml As Xml.XmlElement = mXmlDocument.CreateElement("ACCEPT")
            AcceptXml.SetAttribute("TARGET", StrTarget)
            AcceptXml.SetAttribute("FUNCTION", StrSource.Replace("(", String.Empty).Replace(")", String.Empty))
            Return AcceptXml
        Else
            Return Nothing
        End If
    End Function
End Class
''' <summary>
''' CALL相关类
''' </summary>
''' <remarks></remarks>
Public Class clsStatementCall
    ''' <summary>
    ''' CALL语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateCALL(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        Dim strMethodName As String = mStatement.GetAttribute("METHOD")
        If mStatement.GetAttribute("TYPE") = "Perform" Then
            strLine = GetSpace() & "PERFORM  %MethodName"
        Else
            strLine = GetSpace() & "CALL  %MethodName"
        End If
        strLine = strLine.Replace("%MethodName", clsJustifyStatement.LastModifyVarName(mStatement.GetAttribute("METHOD")))
        Dim ArgList As New List(Of String)
        For Each SubNode As XmlElement In mStatement.ChildNodes
            If SubNode.Name = "ARG" Then
                ArgList.Add(SubNode.GetAttribute("ARGNAME"))
            End If
        Next
        Dim LengthOfString As Integer
        If ArgList.Count > 0 Then
            strLine &= "  USING  "
            LengthOfString = strLine.Length
            strLine &= ArgList(0)
        End If
        strRtn.Add(strLine)
        If ArgList.Count > 1 Then
            For i As Byte = 1 To ArgList.Count - 1
                strRtn.Add(Space(LengthOfString) & ArgList(i))
            Next
        End If
        strRtn.Item(strRtn.Count - 1) &= IIf(Deepth = 1, ".", String.Empty)
        Return strRtn
    End Function
    ''' <summary>
    ''' 调节CALL语句
    ''' </summary>
    ''' <param name="CallXml"></param>
    ''' <param name="PreProcess"></param>
    ''' <param name="AfterProcess"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function JustifyCall(ByVal CallXml As XmlElement, ByVal PreProcess As clsStatementBlock, ByVal AfterProcess As clsStatementBlock) As XmlElement
        Dim MethodName As String
        MethodName = CallXml.GetAttribute("METHOD")
        Select Case MethodName
            Case "PLIRETC"
                'PLIRETC(Value) 将制定值作为程序返回值
                Dim MoveXml As XmlElement = mXmlDocument.CreateElement("MOVE")
                MoveXml.SetAttribute("TARGET", "RETURN_CODE")
                Dim ArgName As String = CType(CallXml.ChildNodes(0), XmlElement).GetAttribute("ARGNAME")
                MoveXml.SetAttribute("SOURCE", clsJustifyStatement.ModifyTopExpress(ArgName, PreProcess, AfterProcess))
                Return MoveXml
            Case "PLIDUMP"
                '显示内存中的内容,AS390使用CEE3ABD
                'CEE3ABD requests that Language Environment terminate the enclave with an abend.  
                'The issuing of the abend can be either with or without clean-up. 
                'There is no return from this service, nor is there any condition associated with it. 
                CallXml.SetAttribute("METHOD", "CEE3ABD")
                CallXml.SetAttribute("TYPE", "ExternalEntry")
                Dim ArgXml1 As XmlElement = mXmlDocument.CreateElement("ARG")
                ArgXml1.SetAttribute("ARGNAME", "CST_ABCODE")
                CallXml.AppendChild(ArgXml1)
                Dim ArgXml2 As XmlElement = mXmlDocument.CreateElement("ARG")
                ArgXml2.SetAttribute("ARGNAME", "CST_TIMING")
                CallXml.AppendChild(ArgXml2)
        End Select
        '动态调用的调整
        If CallXml.GetAttribute("DYNAMIC") = "TRUE" Then
            Dim MoveXml As XmlElement = mXmlDocument.CreateElement("MOVE")
            MoveXml.SetAttribute("SOURCE", "’" & CallXml.GetAttribute("METHOD") & "’")
            MoveXml.SetAttribute("TARGET", "WK_PGMNAME")
            PreProcess.AddOperation(MoveXml)
            CallXml.SetAttribute("METHOD", "WK_PGMNAME")
        Else
            If CallXml.GetAttribute("TYPE") = "PERFORM" Then
                CallXml.SetAttribute("METHOD", CallXml.GetAttribute("METHOD"))
            Else
                CallXml.SetAttribute("METHOD", "'" & CallXml.GetAttribute("METHOD") & "'")
            End If
        End If
        Return CallXml
    End Function
    ''' <summary>
    ''' 是否为CALL命令
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        If CurrentText.StartsWith("CALL ") Then
            Dim MethodInfo As List(Of String) = clsJustifyStatement.GetMethodNameAndArgs(strwords(1))
            For Each extXml As XmlElement In mDataNode.ExternalEntryList
                '遍历所有外部程序定义
                If extXml.GetAttribute("NAME") = MethodInfo(0) Then
                    '如果在外部程序定义里面存在的话
                    Dim CallXml As Xml.XmlElement = mXmlDocument.CreateElement("CALL")
                    CallXml.SetAttribute("METHOD", MethodInfo(0))
                    If MethodInfo.Count > 1 And MethodInfo(0) <> "PLIDUMP" Then
                        For i As Byte = 1 To MethodInfo.Count - 1
                            Dim ArgXml As XmlElement = mXmlDocument.CreateElement("ARG")
                            ArgXml.SetAttribute("ARGNAME", MethodInfo(i))
                            CallXml.AppendChild(ArgXml)
                        Next
                    End If
                    CallXml.SetAttribute("TYPE", "ExternalEntry")
                    '动态调用
                    If extXml.GetAttribute("DYNAMIC") = "TRUE" Then
                        CallXml.SetAttribute("DYNAMIC", "TRUE")
                    End If
                    Return CallXml
                End If
            Next
            'PERFROM定义
            Dim PerformXml As Xml.XmlElement = mXmlDocument.CreateElement("CALL")
            PerformXml.SetAttribute("METHOD", MethodInfo(0))
            PerformXml.SetAttribute("TYPE", "PERFORM")
            If MethodInfo.Count > 1 And MethodInfo(0) <> "PLIDUMP" Then
                For i As Byte = 1 To MethodInfo.Count - 1
                    Dim ArgXml As XmlElement = mXmlDocument.CreateElement("ARG")
                    ArgXml.SetAttribute("ARGNAME", MethodInfo(i))
                    PerformXml.AppendChild(ArgXml)
                Next
            End If
            Return PerformXml
        Else
            Return Nothing
        End If
    End Function
    Public Enum enmMethodType
        PERFORM
        StaticCall
        DynamicCall
    End Enum
    Public Shared Function GetXml(ByVal MethodName As String, ByVal MethodType As enmMethodType) As XmlElement
        Dim PerformXml As Xml.XmlElement = mXmlDocument.CreateElement("CALL")
        PerformXml.SetAttribute("METHOD", MethodName)
        Select Case MethodType
            Case enmMethodType.PERFORM
                PerformXml.SetAttribute("TYPE", "PERFORM")
            Case enmMethodType.StaticCall
                PerformXml.SetAttribute("TYPE", "ExternalEntry")
                PerformXml.SetAttribute("DYNAMIC", "FALSE")
            Case enmMethodType.DynamicCall
                PerformXml.SetAttribute("TYPE", "ExternalEntry")
                PerformXml.SetAttribute("DYNAMIC", "TRUE")
        End Select
        Return PerformXml
    End Function
End Class
''' <summary>
''' CLOSE相关类
''' </summary>
''' <remarks></remarks>
Public Class clsStatementClose
    ''' <summary>
    ''' CLOSE语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateCLOSE(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        For i As Byte = 0 To mStatement.ChildNodes.Count - 1
            Dim mFile As XmlElement = mStatement.ChildNodes(i)
            If mFile.Name = "FILE" Then
                Dim SingleFileString As String
                SingleFileString = GetSpace() & "CLOSE  %Filename" & IIf(Deepth = 1, ".", String.Empty)
                SingleFileString = SingleFileString.Replace("%Filename", mFile.GetAttribute("FILENAME"))
                strRtn.Add(SingleFileString)
            End If
        Next
        Return strRtn
    End Function
    ''' <summary>
    ''' 是否为CLOSE命令
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        If CurrentText.StartsWith("CLOSE ") Then
            Dim CloseXml As Xml.XmlElement = mXmlDocument.CreateElement("CLOSE")
            Dim SubSentence As List(Of String) = GetSubLinesBySplitMark(CurrentText, ",", SplitStyle.NoSplitMark)
            For i As Byte = 0 To SubSentence.Count - 1
                Dim SingleFile As XmlElement = mXmlDocument.CreateElement("FILE")
                Dim mFileName As String = String.Empty
                Dim IOType As String = String.Empty
                mFileName = GetAttr("FILE", GetSyntaxToken(SubSentence(i)))
                SingleFile.SetAttribute("FILENAME", mFileName)
                CloseXml.AppendChild(SingleFile)
            Next
            Return CloseXml
        Else
            Return Nothing
        End If
    End Function
End Class
''' <summary>
''' COMPUTE相关类
''' </summary>
''' <remarks></remarks>
Public Class clsStatementCompute
    ''' <summary>
    ''' Compute语句的调整
    ''' </summary>
    ''' <param name="ComputeNode"></param>
    ''' <remarks></remarks>
    Shared Function JustifyCompute(ByVal ComputeNode As XmlElement, ByVal PreProcess As clsStatementBlock, ByVal AfterProcess As clsStatementBlock) As XmlElement
        Dim strTarget As String = ComputeNode.GetAttribute("TARGET")
        strTarget = clsJustifyStatement.GetFormalExpress(strTarget, PreProcess, AfterProcess)
        Dim strExpress As String = ComputeNode.GetAttribute("FORMULATE")
        ComputeNode.SetAttribute("FORMULATE", clsJustifyStatement.GetFormalExpress(strExpress, PreProcess, AfterProcess))
        ComputeNode.SetAttribute("TARGET", strTarget)
        If PreProcess.Count > 0 Then
            With PreProcess.SingleStatementList.Item(PreProcess.Count - 1)
                Select Case .Name
                    Case "MOVE"
                        If .GetAttribute("TARGET") = strTarget Then
                            '连锁赋值时，最后一环的合并
                            ComputeNode.SetAttribute("TARGET", .GetAttribute("SOURCE"))
                            PreProcess.SingleStatementList.RemoveAt(PreProcess.Count - 1)
                            RemoveWorkDataByName(strTarget)
                        End If
                End Select
            End With
        End If
        Return ComputeNode
    End Function
    ''' <summary>
    ''' 是否为COMPUTE语句
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        Dim StrSource As String = String.Empty
        Dim StrTarget As String = String.Empty
        For i As Byte = 2 To strwords.Count - 1
            StrSource &= strwords(i) & Space(1)
        Next
        StrSource = StrSource.Trim
        StrTarget = strwords(0).Trim
        'COMPUTER MOVE语句不允许出现运算,如果出现运算符号的话,需要先分解运算符号
        If IsFormulate(StrSource) Then
            Dim ComputerXml As Xml.XmlElement = mXmlDocument.CreateElement("COMPUTE")
            ComputerXml.SetAttribute("TARGET", strwords(0))
            ComputerXml.SetAttribute("FORMULATE", clsJustifyStatement.GetFormulate(StrSource))
            Return ComputerXml
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    '''ADD,SUBSTRACT,DIVIDE,MULTIPLY语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks>对于第三参数(结果长度)和第四参数(结果精度)无法现实</remarks>
    Public Shared Function GenerateFUNC(ByVal mStatement As XmlElement) As List(Of String)
        Dim strRtn As New List(Of String)
        Dim strResult As String = mStatement.GetAttribute("RESULT")
        strResult = clsJustifyStatement.ModifyVarName(strResult)
        Dim strP1 As String = mStatement.GetAttribute("P1")
        strP1 = clsJustifyStatement.ModifyVarName(strP1)
        Dim strP2 As String = mStatement.GetAttribute("P2")
        strP2 = clsJustifyStatement.ModifyVarName(strP2)
        Dim strLine As String = String.Empty
        Dim strFormulate As String = String.Empty
        Select Case mStatement.Name
            Case "ADD"
                strFormulate = "%Func  %p1  TO  %p2"
            Case "SUBTRACT"
                strFormulate = "%Func  %p2  FROM  %p1"
            Case "MULTIPLY"
                strFormulate = "%Func  %p1  BY  %p2"
            Case "DIVIDE"
                strFormulate = "%Func  %p1  BY  %p2"
        End Select
        If OnSizeErrorForMultip Then
            '需要ON SIZE ERROR
            strLine = GetSpace() & strFormulate
            strLine = strLine.Replace("%Func", mStatement.Name)
            strLine = strLine.Replace("%p1", strP1)
            strLine = strLine.Replace("%p2", strP2)
            strRtn.Add(strLine)
            If mStatement.GetAttribute("ROUNDED") = "True" Then
                strLine = GetSpace() & "GIVING  ROUNDED %Result"
            Else
                strLine = GetSpace() & "GIVING  %Result"
            End If
            strLine = strLine.Replace("%Result", strResult)
            strRtn.Add(strLine)
            strLine = GetSpace() & "    ON SIZE ERROR"
            strRtn.Add(strLine)
            strRtn.Add(Space(LeftStart - 1) & "*WRITE ERROR PROCESS HERE*")
            strLine = GetSpace() & "END-%Func" & IIf(Deepth = 1, ".", String.Empty)
            strLine = strLine.Replace("%Func", mStatement.Name)
            strRtn.Add(strLine)
        Else
            '不需要 ON SIZE ERROR
            strLine = GetSpace() & strFormulate
            strLine = strLine.Replace("%Func", mStatement.Name)
            strLine = strLine.Replace("%p1", strP1)
            strLine = strLine.Replace("%p2", strP2)
            strRtn.Add(strLine)
            If mStatement.GetAttribute("ROUNDED") = "True" Then
                strLine = GetSpace() & "GIVING  ROUNDED  %Result" & IIf(Deepth = 1, ".", String.Empty)
            Else
                strLine = GetSpace() & "GIVING  %Result" & IIf(Deepth = 1, ".", String.Empty)
            End If
            strLine = strLine.Replace("%Result", strResult)
            strRtn.Add(strLine)
        End If
        Return strRtn
    End Function
    ''' <summary>
    ''' COMPUTER语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateCOMPUTE(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        Dim strFormulate As String = String.Empty
        strFormulate = mStatement.GetAttribute("FORMULATE")
        strFormulate = GenerateComputeExpress(strFormulate)
        If OnSizeErrorForCompute Then
            '需要ON SIZE ERROR
            If mStatement.GetAttribute("ROUNDED") = "True" Then
                strLine = GetSpace() & "COMPUTE %Target  ROUNDED =  %Formulate" & IIf(Deepth = 1, ".", String.Empty)
            Else
                strLine = GetSpace() & "COMPUTE %Target  =  %Formulate" & IIf(Deepth = 1, ".", String.Empty)
            End If

            strLine = strLine.Replace("%Target", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("TARGET")))
            strLine = strLine.Replace("%Formulate", strFormulate)
            strRtn.Add(strLine)
            strLine = GetSpace() & "    ON SIZE ERROR"
            strRtn.Add(strLine)
            strRtn.Add(Space(LeftStart - 1) & "*WRITE ERROR PROCESS HERE*")
            strLine = GetSpace() & "END-COMPUTE" & IIf(Deepth = 1, ".", String.Empty)
            strRtn.Add(strLine)
        Else
            '不需要 ON SIZE ERROR
            '需要ON SIZE ERROR
            If mStatement.GetAttribute("ROUNDED") = "True" Then
                strLine = GetSpace() & "COMPUTE %Target  ROUNDED =  %Formulate" & IIf(Deepth = 1, ".", String.Empty)
            Else
                strLine = GetSpace() & "COMPUTE %Target  =  %Formulate" & IIf(Deepth = 1, ".", String.Empty)
            End If
            strLine = strLine.Replace("%Target", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("TARGET")))
            strLine = strLine.Replace("%Formulate", strFormulate)
            strRtn.Add(strLine)
        End If
        Return strRtn
    End Function
    ''' <summary>
    ''' 获得计算式的COBOL表达式
    ''' </summary>
    ''' <param name="strExpress"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateComputeExpress(ByVal strExpress As String) As String
        Dim NewWordList As New List(Of String)
        Dim strWordList As List(Of String) = GetSyntaxToken(strExpress)
        If strWordList.Count = 1 Then
            If strExpress.StartsWith("(") And strExpress.EndsWith(")") Then
                Return "(" & GenerateComputeExpress(Mid(strExpress, 2, strExpress.Length - 2)) & ")"
            Else
                Return clsJustifyStatement.ModifyVarName(strExpress)
            End If
        Else
            For Each strSub As String In strWordList
                NewWordList.Add(GenerateComputeExpress(strSub))
            Next
            Return Join(NewWordList.ToArray)
        End If
    End Function
End Class
''' <summary>
''' DISPLAY相关类
''' </summary>
''' <remarks></remarks>
Public Class clsStatementDisplay
    ''' <summary>
    '''DISPLAY语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateDISPLAY(ByVal mStatement As XmlElement) As List(Of String)
        Dim strRtn As New List(Of String)
        Dim strLine As String = String.Empty
        strLine = GetSpace() & "DISPLAY  "
        For Each DataXml As XmlElement In mStatement.ChildNodes
            strLine &= Space(2) & clsJustifyStatement.ModifyVarName(DataXml.GetAttribute("VALUE")) & Space(2)
        Next
        strLine = strLine.TrimEnd & IIf(Deepth = 1, ".", String.Empty)
        strRtn.Add(strLine)
        Return strRtn
    End Function
End Class
''' <summary>
''' EXEC
''' </summary>
''' <remarks></remarks>
Public Class clsStatementEXEC
    ''' <summary>
    '''生成EXEC语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateEXEC(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        Dim ExecLine As String() = EXECList.Item(mStatement.GetAttribute("INDEX") - 1).Split(vbCr)
        Dim FirstLeaderSpace As Byte
        Dim ThisLeaderSpace As Byte
        Dim Token As List(Of String)
        '原来的第一行的前导空格数
        FirstLeaderSpace = ExecLine(0).Length - ExecLine(0).TrimStart.Length
        '获得前导空格数
        For Each subLine As String In ExecLine
            ThisLeaderSpace = subLine.Length - subLine.TrimStart.Length
            Token = GetSyntaxToken(subLine)
            Dim HasRename As Boolean = False
            For i As Byte = 0 To Token.Count - 1
                If Token(i).StartsWith(":") Then
                    Dim orgToken As String
                    '原来变量的字符
                    orgToken = Token(i)
                    Token(i) = Mid(Token(i), 2)
                    Token(i) = ":" & clsJustifyStatement.ModifyVarName(Token(i))
                    '如果有不同的话，HasRename 设为 ON
                    If orgToken <> Token(i) Then HasRename = True
                End If
            Next
            If HasRename Then
                '有不同的话，进行改写
                subLine = Join(Token.ToArray, Space(2))
                '保持空格的相对缩进不变
                strRtn.Add(Space(GetSpace.Length + ThisLeaderSpace - FirstLeaderSpace) & subLine)
            Else
                '没有不同的话，则原封不动的输出
                strRtn.Add(Mid(GetSpace() & subLine, FirstLeaderSpace + 1))
            End If
        Next
        strRtn.Add(GetSpace() & "END-EXEC" & IIf(Deepth = 1, ".", String.Empty))
        Return strRtn
    End Function
    ''' <summary>
    ''' 是否为EXEC语句
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        If CurrentText.StartsWith("EXEC_") Then
            Dim EXECXml As XmlElement = mXmlDocument.CreateElement("EXEC")
            EXECXml.SetAttribute("INDEX", Mid(CurrentText, 6))
            Return EXECXml
        End If
        Return Nothing
    End Function
End Class
''' <summary>
''' FETCH/RELEASE
''' </summary>
''' <remarks></remarks>
Public Class clsStatementFETCH
    ''' <summary>
    ''' 是否为FETCH语句
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        If strwords(0) = "FETCH" Then
            Dim FETCHXml As XmlElement = mXmlDocument.CreateElement("FETCH")
            Dim ExtProgram As String = strwords(1)
            For Each extXml As XmlElement In mDataNode.ExternalEntryList
                If extXml.GetAttribute("NAME") = ExtProgram Then
                    extXml.SetAttribute("DYNAMIC", "TRUE")
                    Exit For
                End If
            Next
            Return FETCHXml
        Else
            Return Nothing
        End If
    End Function
End Class
''' <summary>
''' FUNCTION
''' </summary>
''' <remarks></remarks>
Public Class clsStatementFunction
    ''' <summary>
    '''FUNCTION语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateFunction(ByVal mStatement As XmlElement) As List(Of String)
        Dim strRtn As New List(Of String)
        Dim strLine As String = String.Empty
        Dim strResult As String = clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("RESULT"))
        Select Case mStatement.GetAttribute("NAME")
            Case "MOD"
                strLine = GetSpace() & "COMPUTE " & strResult & "  = FUNCTION  MOD  "
                strLine &= clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("P1")) & "," _
                         & clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("P2")) & ")"
            Case "ADDR"
                strLine = GetSpace() & "SET  " & strResult & "  TO  ADDR OF " & clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("P1"))
            Case "STG", "LENGTH", "STORAGE"
                strLine = GetSpace() & "COMPUTE  " & strResult & "  = FUNCTION LENGTH(" & clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("P1")) & ")"
            Case "SUBSTR"
                If mStatement.GetAttribute("P3") <> String.Empty Then
                    strLine = GetSpace() & "MOVE  %P1(%P2:%P3)  TO %Target"
                    strLine = strLine.Replace("%P1", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("P1")))
                    strLine = strLine.Replace("%P2", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("P2")))
                    strLine = strLine.Replace("%P3", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("P3")))
                Else
                    strLine = GetSpace() & "MOVE  %P1(%P2:X)  TO %Target"
                    strLine = strLine.Replace("%P1", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("P1")))
                    strLine = strLine.Replace("%P2", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("P2")))
                End If
                strLine = strLine.Replace("%Target", strResult)
            Case Else
                strLine = GetSpace() & "COMPUTE " & strResult & "  = FUNCTION  "
                strLine &= Space(2) & mStatement.GetAttribute("NAME") & Space(2) & "("
                strLine &= clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("P1")) & ")"
        End Select
        strLine = strLine.TrimEnd & IIf(Deepth = 1, ".", String.Empty)
        strRtn.Add(strLine)
        Return strRtn
    End Function
End Class
''' <summary>
''' GOTO
''' </summary>
''' <remarks></remarks>
Public Class clsStatementGoto
    ''' <summary>
    '''GOTO语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateGOTO(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        Dim strLabelName As String = mStatement.GetAttribute("LABEL")
        strLine = GetSpace() & "GO TO  " & strLabelName & IIf(Deepth = 1, ".", String.Empty)
        strRtn.Add(strLine)
        Return strRtn
    End Function
    ''' <summary>
    ''' 是否为GOTO语句
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        If strwords(0) = "GOTO" And strwords.Count = 2 Then
            Dim gotoXml As Xml.XmlElement = mXmlDocument.CreateElement("GOTO")
            gotoXml.SetAttribute("LABEL", strwords(1))
            Return gotoXml
        Else
            Return Nothing
        End If
    End Function
End Class
''' <summary>
''' INCLUDE
''' </summary>
''' <remarks></remarks>
Public Class clsStatementInclude
    ''' <summary>
    '''INCLUDE语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateINCLUDE(ByVal mStatement As XmlElement) As List(Of String)
        Dim strRtn As New List(Of String)
        Dim strCopyBook As String = mStatement.GetAttribute("COPYBOOKNAME")
        strRtn.Add(GetSpace() & "COPY  " & strCopyBook & IIf(Deepth = 1, ".", String.Empty))
        Return strRtn
    End Function
    ''' <summary>
    ''' 是否为INCLUDE命令
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function IsStatement(ByVal CurrentText As String) As System.Xml.XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        'INCLUDE
        If strwords(0) = "%INCLUDE" And strwords.Count = 2 Then
            Dim IncludeXml As Xml.XmlElement = mXmlDocument.CreateElement("INCLUDE")
            IncludeXml.SetAttribute("COPYBOOKNAME", strwords(1))
            Return IncludeXml
        Else
            Return Nothing
        End If
    End Function
End Class
''' <summary>
''' INIT相关语句
''' </summary>
''' <remarks></remarks>
Public Class clsStatementInit
    ''' <summary>
    '''INIT语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateINIT(ByVal mStatement As XmlElement) As List(Of String)
        Dim strRtn As New List(Of String)
        Dim strTarget As String = mStatement.GetAttribute("TARGET")
        strRtn.Add(GetSpace() & "INITIALIZE    " & clsJustifyStatement.ModifyVarName(strTarget) & IIf(Deepth = 1, ".", String.Empty))
        Return strRtn
    End Function
    ''' <summary>
    ''' INIT语句的调整
    ''' </summary>
    ''' <param name="InitNode"></param>
    ''' <remarks></remarks>
    Shared Function JustifyInit(ByVal InitNode As XmlElement, ByVal PreProcess As clsStatementBlock, ByVal AfterProcess As clsStatementBlock) As Object
        Dim strTarget As String = InitNode.GetAttribute("TARGET")
        If InStr(strTarget, "*") = 0 Then Return InitNode
        '0.SAVEXX(*,*,*) = ''
        Select Case True
            Case strTarget.EndsWith("(*)")
                strTarget = Mid(strTarget, 1, strTarget.Length - 3)
                strTarget = clsJustifyStatement.LastModifyVarName(strTarget)
                InitNode.SetAttribute("TARGET", strTarget)
                Return InitNode
            Case strTarget.EndsWith("(*,*)")
                strTarget = Mid(strTarget, 1, strTarget.Length - 5)
                strTarget = clsJustifyStatement.LastModifyVarName(strTarget)
                InitNode.SetAttribute("TARGET", strTarget)
                Return InitNode
            Case strTarget.EndsWith("(*,*,*)")
                strTarget = Mid(strTarget, 1, strTarget.Length - 7)
                strTarget = clsJustifyStatement.LastModifyVarName(strTarget)
                InitNode.SetAttribute("TARGET", strTarget)
                Return InitNode
            Case strTarget.EndsWith("(*,*,*,*)")
                strTarget = Mid(strTarget, 1, strTarget.Length - 9)
                strTarget = clsJustifyStatement.LastModifyVarName(strTarget)
                InitNode.SetAttribute("TARGET", strTarget)
                Return InitNode
        End Select
        Return clsStatementMove.JustifyMove(InitNode, PreProcess, AfterProcess)
    End Function
    ''' <summary>
    ''' 获得一个INIT的XML节点
    ''' </summary>
    ''' <param name="TargetName">需要初始化的变量名称</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function GetXMlElement(ByVal TargetName As String) As XmlElement
        Dim InitXml As XmlElement = mXmlDocument.CreateElement("INIT")
        InitXml.SetAttribute("TARGET", TargetName)
        Return InitXml
    End Function
End Class
''' <summary>
''' LABLE相关语句
''' </summary>
''' <remarks></remarks>
Public Class clsStatementLabel
    ''' <summary>
    ''' 是否为LABEL
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        If CurrentText.Trim.EndsWith(":") Then
            Dim LabelXml As Xml.XmlElement = mXmlDocument.CreateElement("LABEL")
            LabelXml.SetAttribute("LABEL", Mid(CurrentText, 1, CurrentText.IndexOf(":")))
            Return LabelXml
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' LABEL语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateLABEL(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        Dim strLabelName As String = mStatement.GetAttribute("LABEL")
        If mStatement.GetAttribute("END") = "True" Then
            strLine = GetSpace() & clsJustifyStatement.ModifyLabelName(strLabelName, True) & IIf(Deepth = 1, ".", String.Empty)
        Else
            strLine = GetSpace() & clsJustifyStatement.ModifyLabelName(strLabelName, False) & IIf(Deepth = 1, ".", String.Empty)
        End If
        strRtn.Add(strLine)
        Return strRtn
    End Function
End Class
''' <summary>
''' LEAVE相关语句
''' </summary>
''' <remarks></remarks>
Public Class clsStatementLeave
    ''' <summary>
    '''LEAVE语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateLeave(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        Dim strLabelName As String = mStatement.GetAttribute("LABEL")
        If strLabelName = String.Empty Then
            strLine = GetSpace() & "NEXT SENTENCE" & IIf(Deepth = 1, ".", String.Empty)
        Else
            strLine = GetSpace() & "GO TO  " & strLabelName & IIf(Deepth = 1, ".", String.Empty)
        End If
        strRtn.Add(strLine)
        Return strRtn
    End Function
    ''' <summary>
    ''' 是否为LEAV命令
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        If strwords(0) = "LEAVE" Then
            Dim LeaveXml As Xml.XmlElement = mXmlDocument.CreateElement("LEAVE")
            If strwords.Count = 2 Then
                LeaveXml.SetAttribute("LABEL", Mid(strwords(1), 2))
            End If
            Return LeaveXml
        Else
            Return Nothing
        End If
    End Function
End Class
''' <summary>
''' MOVE相关语句
''' </summary>
''' <remarks></remarks>
Public Class clsStatementMove
    ''' <summary>
    ''' MOVE语句的调整
    ''' </summary>
    ''' <param name="MoveNode"></param>
    ''' <remarks></remarks>
    Shared Function JustifyMove(ByVal MoveNode As XmlElement, ByVal PreProcess As clsStatementBlock, ByVal AfterProcess As clsStatementBlock) As Object
        '1.BRNOTBL(*).BRNO = '9999';
        '2.SAVEXX(*,*).EOR00 = '9999'
        '3.SAVEXX(*,*,*).MEISAI(*).KMKJ = '9999'
        '4.AVETBL.BRNO(OUTCNT,*)  = 0; 
        Dim strTarget As String = MoveNode.GetAttribute("TARGET")
        Dim strSource As String = MoveNode.GetAttribute("SOURCE")
        Dim strComment As String = MoveNode.GetAttribute("COMMENT")
        If Not clsDataAssist.GetDataItemByDataPath(strTarget) Is Nothing Then
            'SET的补充条件
            If clsDataAssist.GetDataItemByDataPath(strTarget).GetAttribute("TYPE") = "PTR" Then
                '如果目标是指针的情况下,该MOVE为SET
                Dim SetXml As Xml.XmlElement = mXmlDocument.CreateElement("SET")
                SetXml.SetAttribute("TARGET", strTarget)
                SetXml.SetAttribute("SOURCE", strSource)
                SetXml.SetAttribute("COMMENT", strComment)
                For Each CommentXml As XmlElement In MoveNode.ChildNodes
                    SetXml.AppendChild(CommentXml.Clone)
                Next
                Return clsStatementSet.JustifySet(SetXml, PreProcess, AfterProcess)
            End If
        End If
        If Not (strTarget.Contains("(*") Or strTarget.Contains(",*,") Or strTarget.Contains("*)")) Then
            strTarget = clsJustifyStatement.ModifyTopExpress(strTarget, PreProcess, AfterProcess)
            strSource = clsJustifyStatement.ModifyTopExpress(strSource, PreProcess, AfterProcess)
            MoveNode.SetAttribute("SOURCE", strSource)
            MoveNode.SetAttribute("TARGET", strTarget)
            If PreProcess.Count > 0 Then
                '如果PreProcess的最后一步是STRING或者MOVE,且有传递赋值关系,则删除最后一个
                Dim LastPreTarget As String = PreProcess.SingleStatementList(PreProcess.Count - 1).GetAttribute("TARGET")
                Dim TargetArray As String() = strTarget.Split(".")
                Dim SourceArray As String() = strSource.Split(".")
                Select Case PreProcess.SingleStatementList(PreProcess.Count - 1).Name
                    Case "STRING"
                        'TARGET相似的情况
                        For i As Byte = 0 To TargetArray.Length - 1
                            If TargetArray(i) = LastPreTarget Then
                                TargetArray(i) = PreProcess.SingleStatementList(PreProcess.Count - 1).GetAttribute("SOURCE")
                                PreProcess.SingleStatementList.RemoveAt(PreProcess.Count - 1)
                                RemoveWorkDataByName(LastPreTarget)
                            End If
                        Next
                        strTarget = Join(TargetArray, ".")
                        MoveNode.SetAttribute("TARGET", strTarget)
                        'TARGET和SOURCE相似的情况
                        For i As Byte = 0 To SourceArray.Length - 1
                            If SourceArray(i) = LastPreTarget Then
                                MoveNode = PreProcess.SingleStatementList(PreProcess.Count - 1).Clone
                                SourceArray(i) = PreProcess.SingleStatementList(PreProcess.Count - 1).GetAttribute("SOURCE")
                                PreProcess.SingleStatementList.RemoveAt(PreProcess.Count - 1)
                                RemoveWorkDataByName(LastPreTarget)
                            End If
                        Next
                        strSource = Join(SourceArray, ".")
                        MoveNode.SetAttribute("TARGET", strTarget)
                        MoveNode.SetAttribute("COMMENT", strComment)
                    Case "MOVE"
                        'TARGET相似的情况
                        For i As Byte = 0 To TargetArray.Length - 1
                            If TargetArray(i) = LastPreTarget Then
                                TargetArray(i) = PreProcess.SingleStatementList(PreProcess.Count - 1).GetAttribute("SOURCE")
                                PreProcess.SingleStatementList.RemoveAt(PreProcess.Count - 1)
                                RemoveWorkDataByName(LastPreTarget)
                            End If
                        Next
                        strTarget = Join(TargetArray, ".")
                        MoveNode.SetAttribute("TARGET", strTarget)
                        'TARGET和SOURCE相似的情况
                        For i As Byte = 0 To SourceArray.Length - 1
                            If SourceArray(i) = LastPreTarget Then
                                SourceArray(i) = PreProcess.SingleStatementList(PreProcess.Count - 1).GetAttribute("SOURCE")
                                PreProcess.SingleStatementList.RemoveAt(PreProcess.Count - 1)
                                RemoveWorkDataByName(LastPreTarget)
                            End If
                        Next
                        strSource = Join(SourceArray, ".")
                        MoveNode.SetAttribute("SOURCE", strSource)
                    Case "COMPUTE"
                        'OLD： COMPUTE WK-1 = A
                        '      MOVE WK-1 TO T
                        'NEW   COMPUTE T = A
                        'TARGET和SOURCE相似的情况
                        Dim rtnCompute As XmlElement = Nothing
                        For i As Byte = 0 To SourceArray.Length - 1
                            If SourceArray(i) = LastPreTarget Then
                                SourceArray(i) = PreProcess.SingleStatementList(PreProcess.Count - 1).GetAttribute("SOURCE")
                                rtnCompute = PreProcess.SingleStatementList(PreProcess.Count - 1).Clone
                                rtnCompute.SetAttribute("TARGET", MoveNode.GetAttribute("TARGET"))
                                PreProcess.SingleStatementList.RemoveAt(PreProcess.Count - 1)
                                RemoveWorkDataByName(LastPreTarget)
                                Return rtnCompute
                            End If
                        Next
                End Select
            End If
            Return MoveNode
        End If

        Dim strTargetArray As String() = strTarget.Split(".")
        Dim LoopArray As String = String.Empty
        '获得第一个数组或者唯一的数组
        For Each strTemp As String In strTargetArray
            If LoopArray = String.Empty Then
                If strTemp.IndexOf("(") > 0 Then
                    LoopArray = Mid(strTemp, strTemp.IndexOf("(") + 2, strTemp.Length - strTemp.IndexOf("(") - 2)
                End If
            End If
        Next
        '首先 生成移动目标字符串的路径部分
        strTarget = String.Empty
        For Each strTemp As String In strTargetArray
            If strTemp.IndexOf("(") > 0 Then
                strTarget &= Mid(strTemp, 1, strTemp.IndexOf("(")) & "."
            Else
                strTarget &= strTemp & "."
            End If
        Next
        '去掉尾部多余的最后一个点号
        strTarget = strTarget.TrimEnd(".")
        '根据路径获得唯一元素
        Dim UnitTarget As XmlElement = clsDataAssist.GetDataItemByDataPath(strTarget)
        If UnitTarget Is Nothing Then
            Dim ErrorXml As XmlElement = mXmlDocument.CreateElement("COMMENTITEM")
            ErrorXml.SetAttribute("TEXT", "Can't Find Union Data For Init:" & strTarget)
            MoveNode.AppendChild(ErrorXml)
            LogWriter.WriteLine("*Error:Can't Find Union Data For MOVE")
            LogWriter.WriteLine("*DataName:" & strTarget)
            strSource = clsJustifyStatement.ModifyTopExpress(strSource, PreProcess, AfterProcess)
            Return MoveNode
        Else
            Dim MoveLoop As New LoopNode
            'RepeatList 里面存放着循环次数，
            'RepeatStrList 里面存放着需不需要循环，需要的用*表示
            Dim RepeatList As List(Of Integer) = GetRepeatArray(UnitTarget)
            Dim RepeatStrList As String() = LoopArray.Split(",")

            '接下来 生成移动目标字符串的数组部分
            '如果 RepeatStrList 里面是 星号，则使用 "CNT-PL1-" & RepeatList(i).ToString 来替换
            strTarget &= "("
            For i As Byte = 0 To RepeatStrList.Length - 1
                If RepeatStrList(i) = "*" Then
                    strTarget &= "CNT-PL1-" & RepeatList(i).ToString
                Else
                    strTarget &= RepeatStrList(i)
                End If
                If i <> RepeatStrList.Length - 1 Then
                    strTarget &= ","
                End If
            Next
            strTarget &= ")"

            '清除不需要的循环
            Dim RealRepeatLoop As New List(Of Integer)
            For i As Byte = 0 To RepeatStrList.Length - 1
                If RepeatStrList(i) = "*" Then
                    '只有是 星号的才需要 循环
                    RealRepeatLoop.Add(RepeatList(i))
                End If
            Next
            '构建循环
            Dim ProcLoop As LoopNode
            ProcLoop = MoveLoop
            For i As Integer = 0 To RealRepeatLoop.Count - 1
                ProcLoop.LoopTo = RealRepeatLoop(i)
                ProcLoop.LoopVarName = "CNT-PL1-" & RealRepeatLoop(i).ToString
                If mDataNode.CntList.Contains(RealRepeatLoop(i)) = False Then
                    mDataNode.CntList.Add(RealRepeatLoop(i))
                End If
                If i <> RealRepeatLoop.Count - 1 Then
                    '非最内层循环
                    Dim NewLoop As New LoopNode
                    ProcLoop.LoopList.AddLoop(NewLoop)
                    ProcLoop = NewLoop
                Else
                    '最内层循环
                    strSource = clsJustifyStatement.ModifyTopExpress(strSource, PreProcess, AfterProcess)
                    '如果PreProcess的最后一步是STRING，则换MOVE为STRING
                    If PreProcess.Count > 0 Then
                        If PreProcess.SingleStatementList(PreProcess.Count - 1).Name = "STRING" Then
                            MoveNode = PreProcess.SingleStatementList(PreProcess.Count - 1).Clone
                            '删除WK_PL_变量
                            RemoveWorkDataByName(MoveNode.GetAttribute("TARGET"))
                            MoveNode.SetAttribute("COMMENT", strComment)
                            PreProcess.SingleStatementList.RemoveAt(PreProcess.Count - 1)
                        End If
                    End If
                    MoveNode.SetAttribute("TARGET", strTarget)
                    MoveNode.SetAttribute("SOURCE", strSource)

                    Dim DummyNode As XmlElement = MoveNode.CloneNode(False)
                    For Each SubXml As XmlNode In MoveNode.ChildNodes
                        If SubXml.Name = "COMMENTLIST" Then
                            ProcLoop.CommentList.Add(SubXml.Clone)
                        Else
                            DummyNode.AppendChild(SubXml.Clone)
                        End If
                    Next
                    MoveNode = DummyNode
                    ProcLoop.LoopList.AddOperation(MoveNode)
                End If
            Next
            strSource = clsJustifyStatement.ModifyTopExpress(strSource, PreProcess, AfterProcess)
            Return MoveLoop
        End If
    End Function
    ''' <summary>
    ''' 获得REPEAT数
    ''' </summary>
    ''' <param name="DataNode"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function GetRepeatArray(ByVal DataNode As XmlElement) As List(Of Integer)
        Dim RepeatStack As New Stack(Of Integer)
        Dim strRepeat As String
        Dim RepeatList As New List(Of Integer)
        strRepeat = DataNode.GetAttribute("REPEAT")
        Do Until DataNode.ParentNode Is Nothing
            If strRepeat <> String.Empty Then
                Dim LineList As String() = strRepeat.Split(",")
                For i As Byte = 1 To LineList.Length
                    If LineList(LineList.Length - i) <> "1" Then RepeatStack.Push(LineList(LineList.Length - i))
                Next
            End If
            DataNode = DataNode.ParentNode
            strRepeat = DataNode.GetAttribute("REPEAT")
        Loop
        Do Until RepeatStack.Count = 0
            RepeatList.Add(RepeatStack.Pop)
        Loop
        Return RepeatList
    End Function
    ''' <summary>
    ''' MOVE语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateMOVE(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        Dim strSource As String = mStatement.GetAttribute("SOURCE").Trim
        Dim strTarget As String = mStatement.GetAttribute("TARGET").Trim
        If strSource = strTarget Then Return strRtn
        If strSource.EndsWith("'B") Then
            'BIT型的转换
            If strSource = "'1'B" Or strSource = "'0'B" Then
                strSource = Mid(strSource, 1, strSource.Length - 1)
            Else
                strRtn.Add(Space(LeftStart - 1) & "*ERROR: MOVE METHOD ERROR Pls Check the BIT Data*")
                LogWriter.WriteLine("*ERROR: MOVE METHOD ERROR Pls Check the BIT Data*")
                LogWriter.WriteLine("SOURCE  :" & mStatement.GetAttribute("SOURCE"))
                LogWriter.WriteLine("TARGET  :" & mStatement.GetAttribute("TARGET"))
            End If
        End If
        Dim strSourceLine As String
        If mStatement.GetAttribute("BYNAME") = "True" Then
            strRtn.Add(Space(LeftStart - 1) & "*WARNING: Pls Check Is The Data Contain Sub Array Data *")
            LogWriter.WriteLine("*WARNING: Pls Check Is The Data Contain Sub Array Data *")
            LogWriter.WriteLine("SOURCE  :" & mStatement.GetAttribute("SOURCE"))
            LogWriter.WriteLine("TARGET  :" & mStatement.GetAttribute("TARGET"))
            strSourceLine = GetSpace() & "MOVE  %All  CORRESPONDING  %Source"
        Else
            strSourceLine = GetSpace() & "MOVE  %All  %Source"
        End If
        strSourceLine = strSourceLine.Replace("%Source", clsJustifyStatement.ModifyVarName(strSource))
        If mStatement.GetAttribute("ALL") = String.Empty Then
            strSourceLine = strSourceLine.Replace(" %All ", String.Empty)
        Else
            strSourceLine = strSourceLine.Replace(" %All ", " ALL ")
        End If

        If strSourceLine.Length < 24 Then
            strSourceLine = Mid(strSourceLine & Space(24), 1, 24)
        End If
        strTarget = "  TO  %Target".Replace("%Target", clsJustifyStatement.ModifyVarName(strTarget)) & IIf(Deepth = 1, ".", String.Empty)
        If (strSourceLine & strTarget).Length > 70 Then
            strRtn.Add(strSourceLine)
            strRtn.Add(GetSpace() + strTarget)
        Else
            strLine = strSourceLine & strTarget
            strRtn.Add(strLine)
        End If
        Return strRtn
    End Function
    ''' <summary>
    '''STRING语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateSTRING(ByVal mStatement As XmlElement) As List(Of String)
        Dim strRtn As New List(Of String)
        Dim strLine As String = String.Empty
        strLine = GetSpace() & "STRING" & Space(Indent)
        For Each subXml As XmlElement In mStatement.ChildNodes
            If subXml.Name = "SUBSTRING" Then
                If Not strLine = String.Empty Then
                    strLine = strLine & clsJustifyStatement.ModifyVarName(subXml.GetAttribute("TEXT").Trim) & "  DELIMITED BY SIZE"
                    strRtn.Add(strLine)
                    strLine = String.Empty
                Else
                    strRtn.Add(GetSpace() & Space("STRING".Length + Indent) & clsJustifyStatement.ModifyVarName(subXml.GetAttribute("TEXT").Trim) & "  DELIMITED BY SIZE")
                End If
            End If
        Next
        Dim strTarget As String = clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("TARGET"))
        strRtn.Add(GetSpace() & "INTO  " & strTarget & IIf(Deepth = 1, ".", String.Empty))
        Return strRtn
    End Function
    ''' <summary>
    ''' 是否为 ACCEPT，SET(是否含有ADDR),MOVE,COMPUTE 命令
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks>STRING命令将在后期转换生成
    ''' </remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strTokens As List(Of String) = GetSyntaxToken(CurrentText)
        If strTokens.Count > 2 AndAlso strTokens(1) = "=" Then
            Dim rtnStatement As XmlElement
            'ACCEPT
            rtnStatement = clsStatementAccept.IsStatement(CurrentText)
            If Not rtnStatement Is Nothing Then
                Return rtnStatement
            End If
            'SET
            rtnStatement = clsStatementSet.IsStatement(CurrentText)
            If Not rtnStatement Is Nothing Then
                Return rtnStatement
            End If
            'COMPUTE
            rtnStatement = clsStatementCompute.IsStatement(CurrentText)
            If Not rtnStatement Is Nothing Then
                Return rtnStatement
            End If

            Dim MoveXml As Xml.XmlElement = mXmlDocument.CreateElement("MOVE")
            Dim StrSource As String = String.Empty
            Dim StrTarget As String = String.Empty
            For i As Byte = 2 To strTokens.Count - 1
                StrSource &= strTokens(i) & Space(1)
            Next
            MoveXml.SetAttribute("SOURCE", StrSource)
            MoveXml.SetAttribute("TARGET", strTokens(0))
            StrSource = StrSource.Trim
            StrTarget = strTokens(0).Trim

            'BYNAME
            If strTokens(strTokens.Count - 2) = "BY" And strTokens(strTokens.Count - 1) = "NAME" Then
                MoveXml.SetAttribute("SOURCE", Mid(strTokens(strTokens.Count - 3), 1, strTokens(strTokens.Count - 3).Length - 1))
                MoveXml.SetAttribute("BYNAME", True)
            End If
            'LOW,HIGH 转换为 LowValue 和 HighValue
            If StrSource.StartsWith("LOW(") Then
                MoveXml.SetAttribute("SOURCE", "LOW_VALUE")
            End If
            If StrSource.StartsWith("HIGH(") Then
                MoveXml.SetAttribute("SOURCE", "HIGH_VALUE")
            End If
            'MOVE语句的源头是空的话，改为INITIALIZE
            '这个语句最后也可能通过MOVE方法转换输出
            If StrSource = "''" Then
                Dim INITXml As Xml.XmlElement = mXmlDocument.CreateElement("INIT")
                INITXml.SetAttribute("TARGET", strTokens(0))
                Return INITXml
            End If
            Return MoveXml
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 获得一个MOVE节点XML
    ''' </summary>
    ''' <param name="strSource"></param>
    ''' <param name="strTarget"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function GetXmlElement(ByVal strSource As String, ByVal strTarget As String)
        Dim XmlMove As XmlElement = mXmlDocument.CreateElement("MOVE")
        XmlMove.SetAttribute("SOURCE", strSource)
        XmlMove.SetAttribute("TARGET", strTarget)
        Return XmlMove
    End Function
End Class
''' <summary>
''' MARCO相关语句
''' </summary>
''' <remarks></remarks>
Public Class clsStatementMacro
    ''' <summary>
    ''' 是否为MACRO命令
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        If CurrentText.StartsWith("#") Then
            Dim CallXml As Xml.XmlElement = mXmlDocument.CreateElement("MACRO")
            CallXml.SetAttribute("COMMAND", CurrentText)
            Return CallXml
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 调整MACRO
    ''' </summary>
    ''' <param name="MarcoNode"></param>
    ''' <remarks></remarks>
    Public Shared Function JustifyMacro(ByVal MarcoNode As XmlElement, ByVal PreProcess As clsStatementBlock, ByVal AfterProcess As clsStatementBlock) As XmlElement
        Dim strMacro As String = MarcoNode.GetAttribute("COMMAND")
        Dim strMacroName As String
        If InStr(strMacro, "(") > 0 Then
            strMacroName = Mid(strMacro, 2, InStr(strMacro, "(") - 2)
        Else
            strMacroName = Mid(strMacro, 2)
        End If
        Select Case strMacroName
            Case "ICALL"
                clsJRIProject.JustifyCALL(MarcoNode, PreProcess, AfterProcess)
        End Select
        Return MarcoNode
    End Function
End Class
''' <summary>
''' ON CONDITION
''' </summary>
''' <remarks></remarks>
Public Class clsStatementOnCondition
    ''' <summary>
    ''' 是否为ON CONDITION命令
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strToken As List(Of String) = GetSyntaxToken(CurrentText)
        If strToken(0) <> "ON" Then
            Return Nothing
        End If
        '根据第二关键字来取得具体的ON CONDITION
        Select Case strToken(1)
            Case "ENDFILE"
                '生成ENDFILE节点
                'ON ENDFILE     EOF_XXX = 1;
                Dim ENDFILEXml As XmlElement = mXmlDocument.CreateElement("ENDFILE")
                If strToken.Count = 5 Then
                    ENDFILEXml.SetAttribute("FILE", Mid(strToken(1), 9, strToken(1).Length - 9))
                    ENDFILEXml.SetAttribute("EOFFLG", strToken(2))
                    ENDFILEXml.SetAttribute("EOFVAL", strToken(4))
                End If
                If strToken.Count = 6 Then
                    ENDFILEXml.SetAttribute("FILE", Mid(strToken(2), 2, strToken(2).Length - 2))
                    ENDFILEXml.SetAttribute("EOFFLG", strToken(3))
                    ENDFILEXml.SetAttribute("EOFVAL", strToken(5))
                End If
                '将文件结束标志情报放入文件信息中
                For Each mFile As XmlElement In mDataNode.FileList
                    If mFile.GetAttribute("NAME") = ENDFILEXml.GetAttribute("FILE") Then
                        mFile.SetAttribute("EOFFLG", ENDFILEXml.GetAttribute("EOFFLG"))
                        mFile.SetAttribute("EOFVAL", ENDFILEXml.GetAttribute("EOFVAL"))
                        Exit For
                    End If
                Next
                Return ENDFILEXml
            Case "FIXEDOVERFLOW", "FOFL"
                'FIXEDOVERFLOW
            Case "ERROR"
                'ON ERROR BEGIN;
                '             ERROR EXCEPTION HANDLE STATEMENTS
                '         END;
        End Select
        Return Nothing
    End Function
End Class
''' <summary>
''' OPEN相关语句
''' </summary>
''' <remarks></remarks>
Public Class clsStatementOpen
    ''' <summary>
    '''OPEN语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateOPEN(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        For i As Byte = 0 To mStatement.ChildNodes.Count - 1
            Dim mFile As XmlElement = mStatement.ChildNodes(i)
            If mFile.Name = "FILE" Then
                Dim SingleFileString As String
                SingleFileString = GetSpace() & "OPEN  %FILEIO  %Filename" & IIf(Deepth = 1, ".", String.Empty)
                SingleFileString = SingleFileString.Replace("%Filename", mFile.GetAttribute("FILENAME"))
                SingleFileString = SingleFileString.Replace("%FILEIO", Mid(mFile.GetAttribute("IOType") & Space(10), 1, 10))
                strRtn.Add(SingleFileString)
            End If
        Next
        Return strRtn
    End Function
    ''' <summary>
    ''' 是否为OPEN命令
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        If CurrentText.StartsWith("OPEN ") Then
            Dim OpenXml As Xml.XmlElement = mXmlDocument.CreateElement("OPEN")
            Dim SubSentence As List(Of String) = GetSubLinesBySplitMark(CurrentText, ",", SplitStyle.NoSplitMark)
            For i As Byte = 0 To SubSentence.Count - 1
                Dim SingleFile As XmlElement = mXmlDocument.CreateElement("FILE")
                Dim mFileName As String = String.Empty
                Dim IOType As String = String.Empty
                mFileName = GetAttr("FILE", GetSyntaxToken(SubSentence(i)))
                SingleFile.SetAttribute("FILENAME", mFileName)
                For Each XmlFile As XmlElement In mDataNode.FileList
                    If XmlFile.GetAttribute("FILENAME") = mFileName Then
                        IOType = XmlFile.GetAttribute("FILEIO")
                    End If
                Next
                SingleFile.SetAttribute("IOType", IOType)
                OpenXml.AppendChild(SingleFile)
            Next
            Return OpenXml
        Else
            Return Nothing
        End If
    End Function
End Class
''' <summary>
''' READ相关语句
''' </summary>
''' <remarks></remarks>
Public Class clsStatementRead
    ''' <summary>
    '''READ语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateREAD(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        strLine = GetSpace() & "READ  %FileName  INTO  %Area" & IIf(Deepth = 1, ".", String.Empty)
        strLine = strLine.Replace("%FileName", mStatement.GetAttribute("FILE"))
        strLine = strLine.Replace("%Area", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("INTO")))
        strRtn.Add(strLine)
        Return strRtn
    End Function
    ''' <summary>
    ''' 是否为READ语句
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        If HasTOKEN("READ", strwords) AndAlso HasTokenStartWith("FILE(", strwords) AndAlso HasTokenStartWith("INTO(", strwords) Then
            Dim ReadXml As Xml.XmlElement = mXmlDocument.CreateElement("READ")
            ReadXml.SetAttribute("FILE", GetAttr("FILE", strwords))
            ReadXml.SetAttribute("INTO", GetAttr("INTO", strwords))
            SetFileLayout(GetAttr("FILE", strwords), GetAttr("INTO", strwords))
            Return ReadXml
        Else
            Return Nothing
        End If
    End Function
    ''' <summary>
    ''' 设置文件的数据结构
    ''' </summary>
    ''' <param name="FileName"></param>
    ''' <param name="LayOutName"></param>
    ''' <remarks></remarks>
    Public Shared Sub SetFileLayout(ByVal FileName As String, ByVal LayOutName As String)
        If mDataNode.FileList.Count = 0 Then Exit Sub
        For i As Byte = 0 To mDataNode.FileList.Count - 1
            If mDataNode.FileList(i).GetAttribute("FILENAME") = FileName Then
                mDataNode.FileList(i).SetAttribute("LAYOUTNAME", LayOutName)
                Exit Sub
            End If
        Next
    End Sub
End Class
''' <summary>
''' SET相关语句
''' </summary>
''' <remarks></remarks>
Public Class clsStatementSet
    ''' <summary>
    '''SET语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateSET(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        strLine = GetSpace() & "SET  %Target  TO  %Source" & IIf(Deepth = 1, ".", String.Empty)
        strLine = strLine.Replace("%Source", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("SOURCE")))
        strLine = strLine.Replace("%Target", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("TARGET")))
        strRtn.Add(strLine)
        Return strRtn
    End Function
    ''' <summary>
    ''' SET语句的调整
    ''' </summary>
    ''' <param name="SetNode"></param>
    ''' <remarks></remarks>
    Shared Function JustifySet(ByVal SetNode As XmlElement, ByVal PreProcess As clsStatementBlock, ByVal AfterProcess As clsStatementBlock) As XmlElement
        Dim strSource As String = SetNode.GetAttribute("SOURCE")
        Dim strTarget As String = SetNode.GetAttribute("TARGET")
        strSource = clsJustifyStatement.ModifyTopExpress(strSource, PreProcess, AfterProcess)
        strTarget = clsJustifyStatement.ModifyTopExpress(strTarget, PreProcess, AfterProcess)
        SetNode.SetAttribute("SOURCE", strSource)
        SetNode.SetAttribute("TARGET", strTarget)
        For Each LinkageXml In mDataNode.LinkageList
            If LinkageXml.GetAttribute("BASED") = SetNode.GetAttribute("TARGET") Then
                Dim SetXml As XmlElement = mXmlDocument.CreateElement("SET")
                SetXml.SetAttribute("SOURCE", SetNode.GetAttribute("TARGET"))
                SetXml.SetAttribute("TARGET", "ADDR(" & LinkageXml.GetAttribute("NAME") & ")")
                AfterProcess.AddOperation(SetXml)
            End If
        Next
        Return SetNode
    End Function
    ''' <summary>
    ''' 是否为SET
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        Dim StrSource As String = String.Empty
        Dim StrTarget As String = String.Empty
        For i As Byte = 2 To strwords.Count - 1
            StrSource &= strwords(i) & Space(1)
        Next
        StrSource = StrSource.Trim
        StrTarget = strwords(0).Trim
        'SET
        If StrSource.StartsWith("ADDR(") Then
            '如果源头以ADDR开始的情况
            '目标是指针的情况，将在其他地方进行判断
            Dim SetXml As Xml.XmlElement = mXmlDocument.CreateElement("SET")
            SetXml.SetAttribute("TARGET", strwords(0))
            SetXml.SetAttribute("SOURCE", StrSource)
            Return SetXml
        Else
            Return Nothing
        End If
    End Function
End Class
''' <summary>
''' WRITE相关语句
''' </summary>
''' <remarks></remarks>
Public Class clsStatementWrite
    ''' <summary>
    '''WRITE语句
    ''' </summary>
    ''' <param name="mStatement"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GenerateWRITE(ByVal mStatement As XmlElement) As List(Of String)
        Dim strLine As String = String.Empty
        Dim strRtn As New List(Of String)
        strLine = GetSpace() & "WRITE  %FileName  FROM  %Area" & IIf(Deepth = 1, ".", String.Empty)
        strLine = strLine.Replace("%FileName", mStatement.GetAttribute("FILE"))
        strLine = strLine.Replace("%Area", clsJustifyStatement.ModifyVarName(mStatement.GetAttribute("FROM")))
        strRtn.Add(strLine)
        Return strRtn
    End Function
    ''' <summary>
    ''' 是否是WRITE语句
    ''' </summary>
    ''' <param name="CurrentText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shared Function IsStatement(ByVal CurrentText As String) As XmlElement
        Dim strwords As List(Of String) = GetSyntaxToken(CurrentText)
        If HasTOKEN("WRITE", strwords) AndAlso HasTokenStartWith("FILE(", strwords) AndAlso HasTokenStartWith("FROM(", strwords) Then
            Dim WriteXml As Xml.XmlElement = mXmlDocument.CreateElement("WRITE")
            WriteXml.SetAttribute("FILE", GetAttr("FILE", strwords))
            WriteXml.SetAttribute("FROM", GetAttr("FROM", strwords))
            '将文件名称和文件的LayOut关联在一起
            If mDataNode.FileList.Count > 0 Then
                For i As Byte = 0 To mDataNode.FileList.Count - 1
                    If mDataNode.FileList(i).GetAttribute("FILENAME") = GetAttr("FILE", strwords) Then
                        mDataNode.FileList(i).SetAttribute("LAYOUTNAME", GetAttr("FROM", strwords))
                        Exit For
                    End If
                Next
            End If
            Return WriteXml
        Else
            Return Nothing
        End If
    End Function
End Class
